package loader

import (
	"game/game-design/util"
	"reflect"
	"strconv"
)

type DesignParser interface {
	ParseList(value string, eleType reflect.Type) reflect.Value //eleType列表中元素的类型
	ParseStruct(value string, eleType reflect.Type) reflect.Value
}

type DesignTable[T any] struct {
	all    []T
	parser DesignParser
}

type IDesignTable interface {
	SetParser(parser DesignParser)
	Load(designFile *DesignFile)
	FileName() string
	Size() int
	LoadAfterAllReady()
	LoadAfterReady()
	LoadAutoGenerate()
	formValue(objField reflect.Value, value string)
}

func (t *DesignTable[T]) Load(designFile *DesignFile) {
	dataSlice := make([]T, 0, len(designFile.Datas))

	var temp T
	rType := reflect.TypeOf(temp)

	for _, data := range designFile.Datas {
		//结构体的指针
		objPtr := reflect.New(rType.Elem())
		//指针指向的结构体本身
		rValue := objPtr.Elem()
		for i := 0; i < len(designFile.Fields) && i < len(data); i++ {
			fieldName := designFile.Fields[i].Name()
			rField := rValue.FieldByName(fieldName)

			fieldData := data[i]
			t.formValue(rField, fieldData)
		}
		dataObj := objPtr.Interface().(T)
		dataSlice = append(dataSlice, dataObj)
	}
	t.all = dataSlice
	// designTable.LoadAutoGenerate()
	// designTable.LoadAfterReady()
}

func (t *DesignTable[T]) LoadAfterReady() {
	// to be override
}

func (t *DesignTable[T]) LoadAfterAllReady() {
	// to be override
}

func (t *DesignTable[T]) LoadAutoGenerate() {
	// to be override
}

func (t *DesignTable[T]) formValue(objField reflect.Value, value string) {
	if objField.Kind() == reflect.Int32 {
		i32, err := strconv.ParseInt(value, 10, 32)
		if err == nil {
			util.ReflectSetInt(objField, i32)
		}
	} else if objField.Kind() == reflect.Int64 {
		i64, err := strconv.ParseInt(value, 10, 64)
		if err == nil {
			util.ReflectSetInt(objField, i64)
		}
	} else if objField.Kind() == reflect.Float32 {
		f32, err := strconv.ParseFloat(value, 32)
		if err == nil {
			util.ReflectSetFloat(objField, f32)
		}
	} else if objField.Kind() == reflect.String {
		util.ReflectSetString(objField, value)

	} else if objField.Kind() == reflect.Slice {
		if value != "" {
			rValue := t.parser.ParseList(value, objField.Type())
			util.ReflectSetSlice(objField, rValue)
		}
	} else if objField.Kind() == reflect.Struct {
		rValue := t.parser.ParseStruct(value, objField.Type())
		util.ReflectSetStruct(objField, rValue)

	} //TODO Map未有实现
}

func (t *DesignTable[T]) All() []T {
	return t.all
}

func (t *DesignTable[T]) Size() int {
	return len(t.all)
}

func (t *DesignTable[T]) SetParser(parser DesignParser) {
	t.parser = parser
}

// 加载常量
func LoadConst(currTable IDesignTable, constMap map[string]string) {
	rType := reflect.TypeOf(currTable)
	rValue := reflect.ValueOf(currTable)

	for i := 0; i < rType.Elem().NumField(); i++ {
		rField := rType.Elem().Field(i)

		objField := rValue.Elem().FieldByName(rField.Name)
		value, ok := constMap[rField.Name]
		if ok {
			currTable.formValue(objField, value)
		}
	}
}
